package com.soloyogame.anitoys.service.impl;

import java.io.IOException;
import java.io.Serializable;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.soloyogame.anitoys.core.ServersManager;
import com.soloyogame.anitoys.db.bean.AppDictItem;
import com.soloyogame.anitoys.db.commond.Account;
import com.soloyogame.anitoys.db.commond.AccountCoupon;
import com.soloyogame.anitoys.db.commond.AccountDeductibleVoucher;
import com.soloyogame.anitoys.db.commond.AccountPointsLog;
import com.soloyogame.anitoys.db.commond.AccountRankLog;
import com.soloyogame.anitoys.db.commond.Address;
import com.soloyogame.anitoys.db.commond.Coupon;
import com.soloyogame.anitoys.db.commond.DeductibleVoucher;
import com.soloyogame.anitoys.db.commond.Email;
import com.soloyogame.anitoys.db.commond.NotifyTemplate;
import com.soloyogame.anitoys.db.commond.Order;
import com.soloyogame.anitoys.db.commond.OrderSimpleReport;
import com.soloyogame.anitoys.db.commond.Orderdetail;
import com.soloyogame.anitoys.db.commond.Orderlog;
import com.soloyogame.anitoys.db.commond.Orderpay;
import com.soloyogame.anitoys.db.commond.OrdersReport;
import com.soloyogame.anitoys.db.commond.Ordership;
import com.soloyogame.anitoys.db.commond.Product;
import com.soloyogame.anitoys.db.commond.ProductStock;
import com.soloyogame.anitoys.db.commond.ReportInfo;
import com.soloyogame.anitoys.db.commond.SystemSetting;
import com.soloyogame.anitoys.db.dao.AccountDeductibleVoucherDao;
import com.soloyogame.anitoys.db.dao.DeductibleVoucherDao;
import com.soloyogame.anitoys.db.dao.DictItemDao;
import com.soloyogame.anitoys.db.dao.OrderDao;
import com.soloyogame.anitoys.db.dao.OrderDetailDao;
import com.soloyogame.anitoys.db.dao.OrderlogDao;
import com.soloyogame.anitoys.db.dao.OrderpayDao;
import com.soloyogame.anitoys.db.dao.OrdershipDao;
import com.soloyogame.anitoys.db.dao.ProductDao;
import com.soloyogame.anitoys.db.page.PagerModel;
import com.soloyogame.anitoys.service.AccountCouponService;
import com.soloyogame.anitoys.service.AccountFinanceService;
import com.soloyogame.anitoys.service.AccountService;
import com.soloyogame.anitoys.service.AddressService;
import com.soloyogame.anitoys.service.CouponService;
import com.soloyogame.anitoys.service.EmailService;
import com.soloyogame.anitoys.service.OrderService;
import com.soloyogame.anitoys.service.SystemSettingService;
import com.soloyogame.anitoys.util.MD5;
import com.soloyogame.anitoys.util.PropertiesUtil;
import com.soloyogame.anitoys.util.cache.RedisCacheProvider;
import com.soloyogame.anitoys.util.constants.ManageContainer;
import com.soloyogame.anitoys.util.email.Mail;
import com.soloyogame.anitoys.util.email.SendCloud;
import com.soloyogame.anitoys.util.front.FrontContainer;


@Service
public class OrderServiceImpl extends ServersManager<Order, OrderDao> implements OrderService {
	private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
    @Autowired
    @Override
    public void setDao(OrderDao orderDao) {
        this.dao = orderDao;
    }

    @Autowired
	private OrderDetailDao orderdetailDao;
    @Autowired
	private OrderpayDao orderpayDao;
    @Autowired
	private OrdershipDao ordershipDao;
    @Autowired
	private OrderlogDao orderlogDao;
    @Autowired
	private ProductDao productDao;
    @Autowired
	private AccountService accountService;
    @Autowired
	private AddressService addressService;
    @Autowired 
    private CouponService couponService;
    @Autowired
	private DictItemDao dictItemDao;
    @Autowired
    @Qualifier("accountFinanceService")
    private AccountFinanceService accountFinanceService;
    @Autowired
    private AccountDeductibleVoucherDao accountDeductibleVoucherDaoImpl;
	@Autowired
	private RedisCacheProvider redisCacheProvider;
	@Autowired
    private AccountCouponService accountCouponService;
	@Autowired
	private DeductibleVoucherDao deductibleVoucherDao;
	@Autowired
    private SystemSettingService systemSettingService;
	@Resource
	private EmailService emailService;

	public void setAccountService(AccountService accountService) {
		this.accountService = accountService;
	}

	public void setProductDao(ProductDao productDao) {
		this.productDao = productDao;
	}

	public void setOrderpayDao(OrderpayDao orderpayDao) {
		this.orderpayDao = orderpayDao;
	}

	public void setOrderlogDao(OrderlogDao orderlogDao) {
		this.orderlogDao = orderlogDao;
	}

	public void setOrdershipDao(OrdershipDao ordershipDao) {
		this.ordershipDao = ordershipDao;
	}

	public void setOrderdetailDao(OrderDetailDao orderdetailDao) {
		this.orderdetailDao = orderdetailDao;
	}

	/**
	 * 创建订单
	 */
	public Order createOrder(Order parentOrder,String parentAmount) throws Exception 
	{
		if (parentOrder == null) 
		{
			throw new NullPointerException("参数不能为空！");
		}
		//主订单插库操作
		int parentOrderId = dao.insertFront(parentOrder);
		parentOrder.setId(Integer.toString(parentOrderId));
		//子订单列表
		List<Order> sonOrderList = parentOrder.getOrders();
		//子订单插库操作
		for (Order sonOrder : sonOrderList) 
		{
			sonOrder.setParentId(Integer.toString(parentOrderId));
			sonOrder.setCreatedate(parentOrder.getCreatedate());
			sonOrder.setAddTime(parentOrder.getAddTime());
			//sonOrder.setAmount(parentOrder.getAmount());
			int sonOrderId = dao.insertFront(sonOrder);
			//订单详情
			List<Orderdetail> orderdetailList = sonOrder.getOrderdetail();
			for (Orderdetail orderdetail : orderdetailList) 
			{
				orderdetail.setOrderID(Integer.toString(sonOrderId));
				//订单明细信息插库操作
				orderdetailDao.insert(orderdetail);
				//商品砍库操作
				// dao.updateProductStock(orderdetail.getOrderID()) ;
				// 下单 扣下单库存
				if (StringUtils.isNotEmpty(orderdetail.getSpecId())) 
				{
					String product_xdkc_key = orderdetail.getProductID() + ManageContainer.product_xdkc + orderdetail.getSpecId();
					Integer product_xdkcValue = 0;
					Serializable serializable =  redisCacheProvider.get(product_xdkc_key);
					String nullValue = "null";
					if (serializable == null || serializable.toString().equals(nullValue)) 
					{
						throw  new Exception ("商品redis挂了，请联系管理员！");
					} 
					else 
					{
						product_xdkcValue =  Integer.valueOf(JSON.parse(serializable.toString()).toString());
						redisCacheProvider.put(product_xdkc_key, product_xdkcValue - orderdetail.getNumber());
					}
				}
				// 下单扣限购库存
				String product_spxg_key = orderdetail.getProductID() + ManageContainer.product_xgsl;

				Integer product_spxgValue = 0;
				Serializable serializable =  redisCacheProvider.get(product_spxg_key);
				String nullValue = "null";
				if (serializable == null || serializable.toString().equals(nullValue)) 
				{
					Product product = productDao.selectById(String.valueOf(orderdetail.getProductID()));
					redisCacheProvider.put(product_spxg_key,product.getProductRestrictions());
					//throw  new Exception ("商品redis挂了，请联系管理员！");
				} 
				else 
				{
					product_spxgValue =  Integer.valueOf(JSON.parse(serializable.toString()).toString());
					//只有不等于0的时候才处理，0则表示不限购
					if(product_spxgValue!=0){
						redisCacheProvider.put(product_spxg_key, product_spxgValue + orderdetail.getNumber());
					}
				}
			}
			//配送信息插库操作
			sonOrder.setSelectAddressID(parentOrder.getSelectAddressID());
			Ordership ordership = this.createOrdershipInfo(sonOrder);
			ordership.setOrderid(String.valueOf(sonOrderId));
			ordershipDao.insert(ordership);
			//订单创建日志信息插库操作
			Orderlog orderlog = createOrderlogInfo(sonOrder);
			orderlog.setOrderid(String.valueOf(sonOrderId));
			orderlogDao.insert(orderlog);
			//订单支付信息插库操作
			Orderpay orderpay = createOrderpayInfo(sonOrder,parentAmount);
			orderpayDao.insert(orderpay);
		}
		return parentOrder;
	}
	
	/**
	 * 积分使用日志信息
	 * @param order
	 * @return
	 * @author zhangjing
	 */
	private AccountPointsLog createAccountPointsLog(Order order) 
	{
		AccountPointsLog accountPointsLog = new AccountPointsLog();
		accountPointsLog.setUserId(order.getAccount());
		accountPointsLog.setRankCount(order.getAmountExchangeScore());
		accountPointsLog.setIsOrder(1);
		accountPointsLog.setOrderId(order.getId());
		accountPointsLog.setDescription("消费了" + order.getAmountExchangeScore() + "积分");
		return accountPointsLog;
	}
	
	/**
	 * 余额使用日志信息
	 * @param parentOrder
	 * @return
	 * @author zhangjing
	 */
	private AccountRankLog createAccountRankLog(Order parentOrder) {
		AccountRankLog accountRankLog = new AccountRankLog();
		accountRankLog.setUserId(parentOrder.getAccount());
		accountRankLog.setAmountType(1);
		accountRankLog.setAmountCount(Double.parseDouble(parentOrder.getAmount()));
		accountRankLog.setIsOrder(1);
		accountRankLog.setOrderId(parentOrder.getId());
		accountRankLog.setDescription("消费了" + parentOrder.getAmount() + "余额");
		return accountRankLog;
	}
	
	/**
	 * 创建插库的订单支付信息
	 * @param order
	 * @return
	 */
	private Orderpay createOrderpayInfo(Order order,String parentAmount) 
	{
		//创建支付记录对象
		Orderpay orderpay = new Orderpay();
		orderpay.setOrderid(order.getId());
		orderpay.setPaystatus(Orderpay.orderpay_paystatus_n);
		orderpay.setPayamount(Double.valueOf(parentAmount));
		Format format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		orderpay.setCreatetime(format.format(new Date()));
		orderpay.setPaymethod(Orderpay.orderpay_paymethod_alipayescow);
		return orderpay;
	}
	
	/**
	 * 创建插库的订单配送信息
	 * @param order
	 * @return
	 * @author zhangjing
	 */
	public Ordership createOrdershipInfo(Order order) 
	{
		/**
		 * 配送地址信息
		 */
		Ordership ordership = new Ordership();
		logger.info("配送地址id = " + order.getSelectAddressID());
		Address address = addressService.selectById(order.getSelectAddressID());
		if(address == null){
			throw new NullPointerException("根据ID=" + order.getSelectAddressID() + "查询不到配送地址信息！本次请求视为非法！");
		}
		
		AppDictItem dict = dictItemDao.selectDictItemById(address.getProvince());	//获取省份对象
		
		ordership.setProvinceCode(address.getProvinceId());
		if(dict!=null){
			ordership.setProvince(dict.getItemName());
		}
		AppDictItem dict1=dictItemDao.selectDictItemById(address.getCity());//市
		ordership.setCityCode(address.getCity());
		ordership.setCity(dict1.getItemName());
		
		AppDictItem dict2=dictItemDao.selectDictItemById(address.getArea());//区
		ordership.setAreaCode(address.getArea());
		ordership.setArea(dict2.getItemName());
		
		ordership.setShipname(address.getName());
		ordership.setShipaddress(address.getAddress());
		ordership.setPhone(address.getPhone());
		ordership.setTel(address.getMobile());
		ordership.setZip(address.getZip());
		ordership.setSex("1");
		logger.info(ordership.toString());
		return ordership;
	}
	
	/**
	 * 创建插库的订单创建日志信息
	 * @param order
	 * @return
	 */
	private Orderlog createOrderlogInfo(Order order) {
		//记录订单创建日志
		Orderlog orderlog = new Orderlog();
		orderlog.setAccount(order.getAccount());
		orderlog.setContent("【创建订单】用户创建订单。订单总金额："+order.getAmount());
		orderlog.setAccountType(Orderlog.orderlog_accountType_w);
		return orderlog;
	}
		
	@Override
	public List<Order> selectOrderInfo(Order order) {
		return dao.selectOrderInfo(order);
	}

	/**
     * 支付宝支付回调
     * @param trade_status
     * @param out_trade_no
     * @param trade_no
     * @param payType 预售订单（1:定金支付2：补款支付）现货订单此值为null
     * @param alipayType （1:实时2：异步）
     * @return
     */
    public boolean alipayNotify(String trade_status, String out_trade_no, String trade_no,String payType,String alipayType,HttpSession session) 
    {
        synchronized (FrontContainer.alipay_notify_lock) {
            logger.error("trade_status = " + trade_status  + ",out_trade_no = " + out_trade_no + ",trade_no = " + trade_no);
            if (StringUtils.isBlank(trade_status) || (StringUtils.isBlank(out_trade_no)
                    && StringUtils.isBlank(trade_no))) {
                logger.error("请求非法!");
                return false;
            }

            String orderCode;
            if (out_trade_no.startsWith("test")) {
                //此处做一个说明,localhost或127.0.0.1下的订单的请求发给支付宝的商户订单号都是test开头的，正式的都是非test开头的。
                //可以参见OrdersAction.createPayInfo()方法。
                orderCode = out_trade_no.substring(4);
            } else {
                orderCode = out_trade_no;
            }
            logger.info("订单号：" + orderCode);
            Order orderParam = new Order();
            orderParam.setOrderCode(orderCode);
            Order parentOrder = new Order();
            Order order = dao.selectFrontOne(orderParam);
            //如果parentId不等于0则表示是子订单
            if(!order.getParentId().equals("0")){
            	Order parentOrderParam = new Order();
            	parentOrderParam.setId(order.getParentId());
            	parentOrder = dao.selectFrontOne(parentOrderParam);
            }else{
            	parentOrder=order;
            }
            logger.info("更新订单支付信息");
            if (session.getAttribute("payWay") != null) {
                // 支付方式
                String payWay = session.getAttribute("payWay").toString();
                String payAccountAmount = (String) session.getAttribute("payAccountAmount");
                // 获取session
                String payBaoAmount = (String) session.getAttribute("payBaoAmount");
                parentOrder.setPayBaoAmount(payBaoAmount);
                parentOrder.setPayAccountAmount(payAccountAmount);
                updateInfoAfterPay(parentOrder, trade_no,payWay,payType,alipayType);
                if ("allWay".equals(payWay)) {
                    // 获取用户信息
                    Account account = (Account) session.getAttribute(FrontContainer.USER_INFO);
                    //扣减客户账户余额
                    accountFinanceService.cutAccountAmount(account.getId(), payAccountAmount);
                }
            }
            return true;
        }
    }

	/**
	 * 更新订单的退款状态
	 * @param orderid	订单ID
	 * @param refundStatus	退款状态
	 */
	private void updateRefundStatus(String orderid,String refundStatus){
		Order order = new Order();
		order.setId(orderid);
		order.setRefundStatus(refundStatus);
		dao.update(order);
	}
	
	/**
	 * 插入订单操作日志
	 * @param order	订单ID
	 * @param content	日志内容
	 */
	private void insertOrderlog(Order order,String content) {
		Orderlog orderlog = new Orderlog();
		orderlog.setOrderid(order.getId());//订单ID
		orderlog.setAccount(order.getAccount());//操作人账号
		orderlog.setContent(content);//日志内容
		orderlog.setAccountType(Orderlog.orderlog_accountType_p);
		orderlogDao.insert(orderlog);
	}

	@Override
	public OrderSimpleReport selectOrdersSimpleReport(String account) {
		return dao.selectOrdersSimpleReport(account);
	}
	
	@Override
	public boolean updateOrderStatusByConfirm(Orderlog orderlog) {
		if(!StringUtils.isBlank(orderlog.getStatus())){
			Order e = new Order();
			e.setId(orderlog.getOrderid());
			if(Orderlog.operate_status_c.equals(orderlog.getStatus())){
				e.setStatus(Order.order_status_file);
				e.setReceiptTime(new Date());
				e.setCompleteTime(new Date());
			}else if(Orderlog.operate_status_q.equals(orderlog.getStatus())){
				e.setStatus(Order.order_status_cancel);
			}
			dao.updateOrderByReceipt(e);
			orderlogDao.insert(orderlog);
		}
		return true;
	}

	/**
	 * 更新商品库存
	 * wuxiongxiong
	 * @param ps,商品ID、购买数量
	 * @return
	 */
	@Override
	public boolean updateProductStock(ProductStock ps) {
		boolean flag = false ;
		int updateResult = dao.updateProductStock(ps.getOrderId()) ;
		if(updateResult==0){
			flag =true ;
		}
		return  flag ;
	}
	
	
	@Override
	public boolean addProductStock(ProductStock ps) {
		boolean flag = false ;
		int updateResult = dao.addProductStock(ps.getOrderId()) ;
		if(updateResult==0){
			flag =true ;
		}
		return  flag ;
	}

	@Override
	public Ordership selectOrdership(Ordership e) {
		return ordershipDao.selectOne(e);
	}
	
	public Order selectOrderById(String id) {
		return dao.selectById(id);
	}

	/**
	 * 根据订单好查询子订单
	 * @param or
	 * @return
	 */
	public List<Order> selectSonOrderList(Order or) {
		return dao.selectSonOrderList(or);
	}

	@Override
	public List<AccountPointsLog> selectOrderPoints(AccountPointsLog e) {
		List<AccountPointsLog> list = dao.selectOrderPoints(e);
		return list;
	}
	
	@Override
	public int updateOrderIsSaleorderById(String id) {
		return dao.updateOrderIsSaleorderById(id);
	}

	@Override
	public boolean payOrderStatus(String orderCode) {
 		String commonOrderCode="";
		//先判断是否是分单；
		Order qryOrder = new Order();
		qryOrder.setOrderCode(orderCode);
		Order sonOrder = dao.selectFrontOne(qryOrder);
		if(sonOrder.getParentId() != null && 
				!"".equals(sonOrder.getParentId()) && 
				!"0".equals(sonOrder.getParentId())) {
			Order pareOrder = dao.selectById(sonOrder.getParentId());
			commonOrderCode=pareOrder.getOrderCode();
		} else {
			commonOrderCode=sonOrder.getOrderCode();
		}
		//判断订单是否是已支付完毕
		Order order=new Order();
		order.setOrderCode(commonOrderCode);
		List<Order> sonOrderList = dao.selectSonOrderList(order);
		for(Order sonOrders : sonOrderList) {
			if (!Orderpay.orderpay_paystatus_y.equals(sonOrders.getPaystatus())) {
				//如果子订单是预售单且提交过来的是母订单
				if(sonOrder.getParentId().equals("0") && sonOrders.getOrderType()==2 && sonOrders.getPaystatus().equals(Order.order_paystatus_p)){
					return true;
				}
				else
				return false;
			}
		}
		return true;
	}

	@Override
	public void updatePayMonery(Order e,String account) 
	{
		
		if(StringUtils.isBlank(e.getId()) || StringUtils.isBlank(account))
		{
			throw new NullPointerException("修改失败，参数不能为空！");
		}
		if(Double.valueOf(e.getAmount()) < 0)
		{
			throw new NullPointerException("修改失败，订单总金额不能小于0!");
		}
		
		if(StringUtils.isBlank(e.getUpdatePayMoneryRemark()))
		{
			insertOrderlog(e.getId(),"【修改订单总金额】总金额修改为："+e.getAmount(),account);
		}
		else
		{
			insertOrderlog(e.getId(),"【修改订单总金额】总金额修改为："+e.getAmount()+"，修改人输入备注："+e.getUpdatePayMoneryRemark(),account);
		}
		
		e.setUpdateAmount("y");//标记订单总金额被后台管理员修改过
		e.setPtotal(e.getAmount());//商品总金额设置为订单总支付金额
		e.setFee("0");//配送费设置为0
		dao.updatePayMonery(e);
	}
	
	@Override
	public List<Order> selectCancelList(Order order) 
	{
		return dao.selectCancelList(order);
	}
	
		/**
		 * 插入订单操作日志
		 * @param orderid	订单ID
		 * @param content	日志内容
		 */
		private void insertOrderlog(String orderid,String content,String account) 
		{
			Orderlog orderlog = new Orderlog();
			orderlog.setOrderid(orderid);//订单ID
			orderlog.setAccount(account);//操作人账号
			orderlog.setContent(content);//日志内容
			orderlog.setAccountType(Orderlog.orderlog_accountType_m);
			orderlogDao.insert(orderlog);
		}

		@Override
		public void cancelOrderByID(String id) 
		{
			if(StringUtils.isBlank(id))
			{
				return;
//				throw new NullPointerException("订单ID不能为空！");
			}
			Order order = new Order();
			order.setId(id);
			order.setStatus(Order.order_status_cancel);
			dao.update(order);
			
			insertOrderlog(id,"【系统取消】一周内未完全支付并且未审核的订单，系统自动将其取消。", "system");
		}

		@Override
		public List<ReportInfo> selectOrderSales(Order order) 
		{
			return dao.selectOrderSales(order);
		}
		
		@Override
		public List<ReportInfo> selectProductSales(Order order) 
		{
			return dao.selectProductSales(order);
		}

		@Override
		public OrdersReport loadOrdersReport() 
		{
			return dao.loadOrdersReport();
		}
		
		/**
		 * tree分页查询
		 * @param order
		 * @return
		 */
		public PagerModel selectTreePageList(Order order) 
		{
			PagerModel pagerModel = loadRoot(order);
			List<Order> root = pagerModel.getList();
			List<Order> result = Lists.newArrayList();
			for(Order o : root)
			{
				appendChildren(o, result);
			}
			pagerModel.setList(result);
			return pagerModel;
		}
		
		private void appendChildren(Order order, List<Order> list) 
		{
			if(order == null)
			{
				return;
			}
			list.add(order);
			if(order.getChildren() != null && order.getChildren().size() > 0) 
			{
				for (Order cata : order.getChildren()) 
				{
					appendChildren(cata, list);
				}
			}
		}
		
		@Override
		public PagerModel loadRoot(Order order) 
		{
			if (order == null) 
			{
				order = new Order();
			}
			order.setParentId("0");
			PagerModel pagerModel = dao.selectPageList(order);
			List<Order> root = pagerModel.getList();
			for (int i = 0; i < root.size(); i++) 
			{
				Order ee = root.get(i);
				loadChildrenByPid(ee);
			}
			return pagerModel;
		}
		
		/**
		 * 加载指定节点下的全部子节点
		 * @param order
		 */
		private void loadChildrenByPid(Order order) 
		{
			Order e = new Order();
			e.setParentId(order.getId());
			List<Order> children = dao.selectList(e);
			order.setChildren(children);
		}
		
		@Override
		public int update(Order e) {
			return dao.update(e);
		}
		public void updateExpress(Order order) {
			dao.updateExpress(order);
		}
	
		@Override
		public PagerModel selectExpenseRecordsList(Order order) {
			return dao.selectExpenseRecordsList(order);
		}
		
		/**
		 * 支付成功后的更新操作
		 * @param trade_no	交易号
		 * @param payWay	支付方式() 
		 * @param alipayType 1:实时支付2：异步支付
		 * @param payType 1:定金支付2：补款支付
		 * @author jason
		 */
		 public void updateInfoAfterPay(Order parentOrder, String trade_no ,String payWay,String payType,String alipayType)
		{
			//根据父订单号查询出每个子订单list
			Order or = new Order();
			or.setOrderCode(parentOrder.getOrderCode());
			List<Order> sonOrderList = dao.selectSonOrderList(or);
			
			//遍历子订单list
			for(Order sonOrder : sonOrderList) 
			{
				//根据子订单id查询支付记录
				Orderpay qryOrderPay = new Orderpay();
				qryOrderPay.setOrderid(sonOrder.getId());
				/*
				 * 更新子订单相关信息
				 */
				//若子订单类型为2并且子订单状态为待付款，则表明本次为预售单的第一次支付
				if(2 == sonOrder.getOrderType() && Order.order_status_init.equals(sonOrder.getStatus()) && payType.equals("1")) 
				{
					//查询订单的定金支付记录
					Orderpay orderpay = orderpayDao.selectOne(qryOrderPay);
					//实时的支付
					if(alipayType=="1")
					{
						//更新子订单状态到待补款
						sonOrder.setStatus(Order.order_status_pass);
						//更新支付状态为部分支付
						sonOrder.setPaystatus(Order.order_paystatus_p);
						//更新首次支付时间为当前时间
						sonOrder.setPayTime(new Date());
						//更新完成付款时间为当前时间
						sonOrder.setFinishPayTime(new Date());
						//第一次定金支付记录
						orderpay.setPayType("1");
						//更新支付记录为【成功支付】
						orderpay.setOrderid(sonOrder.getId());
						orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
						orderpay.setTradeNo(trade_no);
						orderpay.setPaymethod(payWay);
						orderpayDao.updateFront(orderpay);
						parentOrder.setAmount(sonOrder.getAmount());
					}
					//异步支付
					else if(alipayType=="2")
					{
						//第一次定金支付
						if(StringUtils.isBlank(orderpay.getTradeNo()))
						{
							//更新子订单状态到待补款
							sonOrder.setStatus(Order.order_status_pass);
							//更新支付状态为部分支付
							sonOrder.setPaystatus(Order.order_paystatus_p);
							//更新首次支付时间为当前时间
							sonOrder.setPayTime(new Date());
							//更新完成付款时间为当前时间
							sonOrder.setFinishPayTime(new Date());
							//第一次定金支付记录
							orderpay.setPayType("1");
							//更新支付记录为【成功支付】
							orderpay.setOrderid(sonOrder.getId());
							orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
							orderpay.setTradeNo(trade_no);
							orderpay.setPaymethod(payWay);
							orderpay.setPayamount(Double.valueOf(parentOrder.getPayBaoAmount()));
							orderpayDao.updateFront(orderpay);
							parentOrder.setAmount(sonOrder.getAmount());
						}
					}
				} 
				//若子订单类型为2并且子订单状态为待补款，且子订单的支付状态为部分支付P，则表明本次为预售单的补款支付
				else if(2 == sonOrder.getOrderType() && Order.order_status_pass.equals(sonOrder.getStatus()) && payType.equals("2")) 
				{
					if(alipayType=="1")
					{
						Orderpay orderpay = new Orderpay();
						//更新子订单状态到代发货
						sonOrder.setStatus(Order.order_status_stay);
						//更新子订单支付状态到全部支付
						sonOrder.setPaystatus(Order.order_paystatus_y);
						//添加补款时间为当前时间
						sonOrder.setReplenishmentTime(new Date());
						//更新完成付款时间为当前时间
						sonOrder.setFinishPayTime(new Date());
						orderpay.setPayType("2");
						//创建补款支付记录为【成功支付】
						orderpay.setOrderid(sonOrder.getId());
						orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
						orderpay.setTradeNo(trade_no);
						orderpay.setPayamount(Double.valueOf(parentOrder.getPayBaoAmount()));
						orderpay.setPaymethod(payWay);
						orderpayDao.insertFront(orderpay);
						 //父订单支付状态
		                parentOrder.setPaystatus(Order.order_paystatus_y);
		                parentOrder.setStatus(Order.order_status_stay);
		                //父订单支付时间
		                parentOrder.setPayTime(new Date());
		                
		                sonOrder.setAmount(String.valueOf(Double.valueOf(parentOrder.getAmount())+Double.valueOf(sonOrder.getAmount())));
						parentOrder.setAmount(String.valueOf(Double.valueOf(parentOrder.getAmount())+Double.valueOf(sonOrder.getAmount())));
						parentOrder.setFee(sonOrder.getFee());
						parentOrder.setAmountExchangeScore(sonOrder.getAmountExchangeScore());
		                
					}
					//异步支付
					else if(alipayType=="2")
					{
						qryOrderPay.setPayType("2");
						Orderpay orderpay = orderpayDao.selectOne(qryOrderPay);//查询补款支付记录
						//第一次补款支付
						if(orderpay==null)
						{
							orderpay = new Orderpay();
							//更新子订单状态到代发货
							sonOrder.setStatus(Order.order_status_stay);
							//更新子订单支付状态到全部支付
							sonOrder.setPaystatus(Order.order_paystatus_y);
							//添加补款时间为当前时间
							sonOrder.setReplenishmentTime(new Date());
							//更新完成付款时间为当前时间
							sonOrder.setFinishPayTime(new Date());
							orderpay.setPayType("2");
							//创建补款支付记录为【成功支付】
							orderpay.setOrderid(sonOrder.getId());
							orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
							orderpay.setTradeNo(trade_no);
							orderpay.setPayamount(Double.valueOf(sonOrder.getAmount()));
							orderpay.setPaymethod(payWay);
							orderpayDao.insertFront(orderpay);
							 //父订单支付状态
			                parentOrder.setPaystatus(Order.order_paystatus_y);
			                parentOrder.setStatus(Order.order_status_stay);
			                //父订单支付时间
			                parentOrder.setPayTime(new Date());
						}
					}
				}
				//非预售单支付的更新操作
				else 
				{
					//更新子订单状态到代发货
					sonOrder.setStatus(Order.order_status_stay);
					//更新子订单支付状态到全部支付
					sonOrder.setPaystatus(Order.order_paystatus_y);
					//添加支付时间为当前时间
					sonOrder.setPayTime(new Date());
					//添加完成付款时间为当前时间
					sonOrder.setFinishPayTime(new Date());
	                parentOrder.setPayTime(new Date());
	                //父订单支付状态
	                parentOrder.setPaystatus(Order.order_paystatus_y);
	                parentOrder.setPayType(payWay);
	                parentOrder.setStatus(Order.order_status_stay);
	                //创建补款支付记录为【成功支付】
	                Orderpay orderpay = new Orderpay();
	                orderpay.setOrderid(sonOrder.getId());
	                orderpay = orderpayDao.selectOne(orderpay);
	                orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
	                orderpay.setPayamount(Double.valueOf(sonOrder.getAmount()));
	                orderpay.setPaymethod(payWay);
	                orderpay.setTradeNo(trade_no);
					orderpayDao.updateFront(orderpay);
				}
				dao.updateFront(sonOrder);
				dao.updateFront(parentOrder);
				/*
				 * 插入子订单支付日志
				 */
				String content = "";				//支付内容信息
				if("baoWay".equals(payWay)) {
					content = "【支付宝通知】已付款，等待卖家发货(TRADE_SUCCESS)。";
				} else if("amtWay".equals(payWay)) {
					content = "【账户余额通知】已付款，等待卖家发货(TRADE_SUCCESS)。";
				}
				insertOrderlog(sonOrder, content);
				
				logger.info("sonOrder.getCouponsId() = " + sonOrder.getCouponsId());
				logger.info("sonOrder.getDeductibleId() = " + parentOrder.getDeductibleId());
				/*
				 * 扣减用户所使用优惠券(做更新状态操作)
				 */
				if(StringUtils.isNotBlank(sonOrder.getCouponsId())) {
					Coupon coupon = new Coupon();
					coupon.setUserId(sonOrder.getAccount());
					coupon.setCouponId(sonOrder.getCouponsId());
					coupon.setStatus("2");				//已使用		
					coupon.setUseTime(new Date());
					coupon.setOrderId(sonOrder.getId());
					dao.updateAccountCoupon(coupon);
				}
				/*
				 * 扣减用户平台抵扣券
				 */
				if(StringUtils.isNotBlank(parentOrder.getDeductibleId())) {
					AccountDeductibleVoucher accountDeductibleVoucher = new AccountDeductibleVoucher();
					accountDeductibleVoucher.setUserId(parentOrder.getAccount());
					accountDeductibleVoucher.setId(parentOrder.getDeductibleId());
					accountDeductibleVoucher.setStatus(2);
					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					accountDeductibleVoucher.setUseTime(format.format(new Date()));
					accountDeductibleVoucher.setOrderId(parentOrder.getId());
					accountDeductibleVoucherDaoImpl.update(accountDeductibleVoucher);
				}
			}
			
			//如果支付方式是混合支付则插入余额使用日志
			 if ("allWay".equals(payWay) && StringUtils.isNotBlank(parentOrder.getPayAccountAmount())){
				 	/*
					 * 插入账户余额使用日志
					 */
					AccountRankLog accountRankLog = this.createAccountRankLog(parentOrder);
					orderlogDao.addAccountRankLog(accountRankLog);
			 }
			
			/*
	         * 扣减用户使用积分
			 */
	        accountFinanceService.cutAccountRank(parentOrder.getAccount(),parentOrder.getAmountExchangeScore());
	        /*
	         * 插入用户积分使用日志
			 */
	        AccountPointsLog accountPointsLog = this.createAccountPointsLog(parentOrder);
	        orderlogDao.addAccountPointsLog(accountPointsLog);
	        
            dao.updateFront(parentOrder);
		}
		
		/**
	     * 余额支付成功后的更新操作
	     * @param parentOrder        父订单
	     * @param sonOrderList       子订单
	     * @param payWay             支付方式
	     * @author zhangjing
	     */
	    public void updateInfoAmtWayPay(Order parentOrder, List<Order> sonOrderList, String payWay) 
	    {
	        //遍历子订单list
	        for (Order sonOrder : sonOrderList) 
	        {
	            //根据子订单id查询支付记录
	            Orderpay orderpay = new Orderpay();
	            orderpay.setOrderid(sonOrder.getId());
	            orderpay = orderpayDao.selectOne(orderpay);
	            //若支付记录查询为空，则抛出异常（“根据支付记录号查询不到支付记录信息！”）
	            if (orderpay == null) {
	                throw new NullPointerException("根据支付记录号查询不到支付记录信息！");
	            }
	            //若子订单类型为2并且子订单状态为待付款，则表明本次为预售单的第一次支付
	            if (2 == sonOrder.getOrderType() && Order.order_status_init.equals(sonOrder.getStatus())) {
	                //更新子订单状态到待补款
	                sonOrder.setStatus(Order.order_status_pass);
	                //更新支付状态为部分支付
	                sonOrder.setPaystatus(Order.order_paystatus_p);
	                //更新首次支付时间为当前时间
	                sonOrder.setPayTime(new Date());
	                //更新完成付款时间为当前时间
	                sonOrder.setFinishPayTime(new Date());
	                //支付方式
	                sonOrder.setPayType(payWay);
	                //第一次定金支付记录
	                orderpay.setPayType("1");
	                //更新支付记录为【成功支付】
	                orderpay.setOrderid(sonOrder.getId());
	                orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
		            orderpay.setPaymethod(payWay);
	                orderpayDao.updateFront(orderpay);
	            }
	            //若子订单类型为2并且子订单状态为待补款，则表明本次为预售单的补款支付
	            else if (2 == sonOrder.getOrderType() && Order.order_status_pass.equals(sonOrder.getStatus())) 
	            {
	            	orderpay = new Orderpay();
	            	//更新子订单状态到待发货
	                sonOrder.setStatus(Order.order_status_stay);
	                //更新子订单支付状态到全部支付
	                sonOrder.setPaystatus(Order.order_paystatus_y);
	                //添加补款时间为当前时间
	                sonOrder.setReplenishmentTime(new Date());
	                //更新完成付款时间为当前时间
	                sonOrder.setFinishPayTime(new Date());
	                //支付时间
	                sonOrder.setPayTime(new Date());
	                //支付方式
	                sonOrder.setPayType(payWay);
	                //父订单支付状态
	                parentOrder.setPaystatus(Order.order_paystatus_y);
	                parentOrder.setStatus(Order.order_status_stay);
	                //父订单支付时间
	                parentOrder.setPayTime(new Date());
	                orderpay.setPayType("2");
					//创建补款支付记录为【成功支付】
					orderpay.setOrderid(sonOrder.getId());
					orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
					orderpay.setPayamount(Double.valueOf(parentOrder.getPayAccountAmount()));
					orderpay.setPaymethod(payWay);
					orderpayDao.insertFront(orderpay);
					parentOrder.setAmount(String.valueOf(Double.valueOf(parentOrder.getAmount())+Double.valueOf(sonOrder.getAmount())));
					parentOrder.setFee(sonOrder.getFee());
					parentOrder.setAmountExchangeScore(sonOrder.getAmountExchangeScore());
	            }
	            //非预售单支付的更新操作
	            else 
	            {
	                //更新子订单状态到待发货
	                sonOrder.setStatus(Order.order_status_stay);
	                //更新子订单支付状态到全部支付
	                sonOrder.setPaystatus(Order.order_paystatus_y);
	                //添加支付时间为当前时间
	                sonOrder.setPayTime(new Date());
	                //添加完成付款时间为当前时间
	                sonOrder.setFinishPayTime(new Date());
	                //子订单支付方式
	                sonOrder.setPayType(payWay);
	                //父订单支付状态
	                parentOrder.setPaystatus(Order.order_paystatus_y);
	                parentOrder.setPayType(payWay);
	                parentOrder.setStatus(Order.order_status_stay);
	                //创建补款支付记录为【成功支付】
					orderpay.setOrderid(sonOrder.getId());
					orderpay.setPaystatus(Orderpay.orderpay_paystatus_y);
					orderpay.setPayamount(Double.valueOf(parentOrder.getPayAccountAmount()));
					orderpay.setPaymethod(payWay);
					orderpayDao.updateFront(orderpay);
	            }
	            dao.updateFront(sonOrder);
	            /*
	             * 插入子订单支付日志
				 */
	            String content = "";                //支付内容信息
	            if ("amtPay".equals(payWay) || "amtWay".equals(payWay)) {
	                content = "【账户余额通知】已付款，等待卖家发货(TRADE_SUCCESS)。";
	            }
	            insertOrderlog(sonOrder, content);
	            /*
	             * 扣减用户所使用优惠券(做更新状态操作)
				 */
	            String couponsId = sonOrder.getCouponsId();
	            if (StringUtils.isNotBlank(couponsId)) {
	                Coupon coupon = new Coupon();
	                coupon.setUserId(sonOrder.getAccount());
	                coupon.setId(couponsId);
	                coupon.setStatus("2");                //已使用
	                coupon.setUseTime(new Date());
	                coupon.setOrderId(sonOrder.getId());
	                dao.updateAccountCoupon(coupon);
	                AccountCoupon accountCoupon = accountCouponService.selectById(couponsId);
	                //刷新优惠券的使用数
	                Coupon c = new Coupon();
	                c.setUseCount(1);
	                c.setId(accountCoupon.getCouponId());
	                couponService.update(c);
	            }
	        }
	            /*
	             * 扣减用户平台抵扣券
				 */
	        String deductibleId = parentOrder.getDeductibleId();
	        if (StringUtils.isNotBlank(deductibleId)) 
	        {
	            AccountDeductibleVoucher accountDeductibleVoucher = new AccountDeductibleVoucher();
	            accountDeductibleVoucher.setUserId(parentOrder.getAccount());
	            //TODO 不确定哪个是折扣券唯一标式符
	            accountDeductibleVoucher.setDeductibleSn(deductibleId);
	            accountDeductibleVoucher.setId(deductibleId);
	            accountDeductibleVoucher.setStatus(2); //已使用
	            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	            accountDeductibleVoucher.setUseTime(format.format(new Date()));
	            accountDeductibleVoucher.setOrderId(parentOrder.getId());
	            accountDeductibleVoucherDaoImpl.update(accountDeductibleVoucher);
	           
	            AccountDeductibleVoucher accountDeductibleVoucher1 = accountDeductibleVoucherDaoImpl.selectById(deductibleId);
	          //刷新优惠券的使用数
	            DeductibleVoucher d = new DeductibleVoucher();
                d.setUseCount(1);
                d.setId(accountDeductibleVoucher1.getDeductibleId());
                deductibleVoucherDao.update(d);
	        }
	        
	        /*
	         * 插入账户余额使用日志
			 */
	        AccountRankLog accountRankLog = this.createAccountRankLog(parentOrder);
	        orderlogDao.addAccountRankLog(accountRankLog);
	        /*
	         * 扣减用户使用积分
			 */
	        accountFinanceService.cutAccountRank(parentOrder.getAccount(),parentOrder.getAmountExchangeScore());
	        /*
	         * 插入用户积分使用日志
			 */
	        AccountPointsLog accountPointsLog = this.createAccountPointsLog(parentOrder);
	        orderlogDao.addAccountPointsLog(accountPointsLog);
	        
            dao.updateFront(parentOrder);
	    }

	    /**
	     * cart 结算页确认支付创建订单
	     */
		public int insertFront(Order e) {
			return dao.insertFront(e);
		}

		 /**
	     * cart 查询订单
	     * @param e
	     * @return
	     */
		public Order selectFrontOne(Order e) 
		{
			return dao.selectFrontOne(e);
		}

		 /**
	     * 个人中心中查询订单列表
	     * @param e
	     * @return
	     */
		public List selectFrontList(Order e) 
		{
			return dao.selectFrontList(e);
		}

		/**
	     * 个人中心查询分页订单列表
	     */
		public PagerModel selectFrontPageList(Order e) {
			return dao.selectFrontPageList(e);
		}
		
		/**
		 * 给指定邮箱发送邮件
		 * @param e
		 */
		public void sendEmail(Account e,String emailNotifyTemplateCode,Order order)
		{
			if(e==null || StringUtils.isBlank(e.getAccount()))
			{
				throw new NullPointerException("参数不能为空！");
			}
			String sign = System.currentTimeMillis()+e.getAccount()+e.getEmail();
			
			//存储发送的邮件
			Email email = new Email();
			email.setAccount(e.getAccount());
			email.setType(emailNotifyTemplateCode);         //Email.email_type_forget);
			email.setSign(MD5.md5(sign));
			
			String url = null;                              //发送邮件的链接
			String emailTitle = null;                       //保存邮件的标题
			SystemSetting systemSetting = systemSettingService.selectOne((com.soloyogame.anitoys.db.commond.SystemSetting) new SystemSetting());
			if(emailNotifyTemplateCode.equals(NotifyTemplate.email_cancle_order))
			{
				//取消订单邮件
				url = systemSetting.getMy()+"/account/reset.html?sign="+email.getSign();
				emailTitle = "取消"+order.getOrderCode()+"订单";
			}
			email.setUrl(url);
			Date dd = new Date();
			email.setStarttime(String.valueOf(dd.getTime()));                     //当前时间
			email.setEndtime(String.valueOf(DateUtils.addHours(dd, 2).getTime()));//当前时间+2小时
			email.setNewEmail(e.getNewEmail());                                   //新邮箱
			
			logger.error("sign = "+sign+",email.sign = "+email.getSign()+",e.getEmail() = " + e.getEmail());
			//发送邮件到用户的邮箱
			Mail mail = new Mail();
			if(StringUtils.isNotBlank(e.getNewEmail()))
			{
				mail.setReceiver(e.getNewEmail());
			}
			else
			{
				mail.setReceiver(e.getEmail());
			}
			
			Properties  properties = PropertiesUtil.findCommonPro("config.properties");
			final String mailUrl = properties.getProperty("mailUrl");
			final String apiUser = properties.getProperty("apiUser");
			final String apiKey = properties.getProperty("apiKey");
			final String from = properties.getProperty("from");
			final String fromname = properties.getProperty("fromname");
			final String doCancleOrder = properties.getProperty("doCancleOrder"); //找回密码发送邮件的状态（1：发送0：不发送）
			//找回密码邮件通知模板
			final String templateInvokeName = properties.getProperty("email_cancle_order");
			mail.setUrl(mailUrl);
			mail.setApiKey(apiKey);        
			mail.setApiUser(apiUser);
			mail.setSender(from);
			mail.setName(fromname);                         //发件人地址
			mail.setTemplateInvokeName(templateInvokeName); //忘记密码模板
			mail.setReceiverName(e.getAccount());           //收件人姓名
			systemSetting = systemSettingService.selectOne(new SystemSetting());
			mail.setWebName(systemSetting.getName());       //设置网站名称
			mail.setPasswordUrl(url);                       //设置修改密码链接
			mail.setSendTime(new Date());
			mail.setOrderCode(order.getOrderCode());
			
			boolean result=false;
			//状态为1 发送邮件
			if(doCancleOrder.equals("1"))
			{
				try
				{
					result = SendCloud.send_template(mail);
				} 
				catch (IOException e1) 
				{
					e1.printStackTrace();
				}
				if(result)
				{
					email.setSendStatus(Email.email_sendStatus_y);
				}
				else
				{
					email.setSendStatus(Email.email_sendStatus_n);
				}
				emailService.insert(email);
			}
		}

		/**
		 * 保存支付宝支付日志
		 * @param params
		 */
		public int saveAlipayLog(Map<String, String> params) 
		{
			return dao.saveAlipayLog(params);
		}
}
